////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011-2012 www.iflytek.com. All Rights Reserved.
//  This software for customer relationship management system, developed by Iflytek-ZY-GCZX team.
//  Software code and design for the team, copy rights reserved.
////////////////////////////////////////////////////////////////////////////////

package com.iflytek.ci.common.exceptions;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * <p>
 * Exception处理的工具类.
 * </p>
 *
 * @author poplar.yfyang
 * @version 1.0 2012-11-18 12:29 PM
 * @since JDK 1.5
 */
public class ExceptionSupporter {

	public static final String defaultPrefixPackage = "com.cpic.p17";

	/**
	 * 得到最原始的异常
	 *
	 * @param t
	 * @return
	 */
	public static Throwable getRootCause(Throwable t) {
		while (t.getCause() != null) t = t.getCause();
		return t;
	}

	/**
	 * 得到关注的堆栈信息
	 *
	 * @param t
	 * @return
	 */
	public static String getCarefulStackTrace(Throwable t) {
		return getCarefulStackTrace(t, defaultPrefixPackage);
	}

	/**
	 * 查找到我们需要注意的StackTrace，将抛弃我们不需要关心的堆栈信息。
	 * 具体采用递归的方式查询到我们必须关心的异常信息。
	 *
	 * @param t
	 * @param packageStart
	 * @return
	 */
	public static String getCarefulStackTrace(Throwable t, String packageStart) {
		String causeString = null;
		if (t.getCause() != null) {
			causeString = getCarefulStackTrace(t.getCause(), packageStart);
		}
		//1、先将异常类名和Message写出来；
		StringBuffer sb = new StringBuffer(t.getClass().getName());
		sb.append(":").append(t.getMessage()).append("\n");
		//2、过滤需要关心的堆栈信息
		StackTraceElement[] traceElements = t.getStackTrace();
		boolean lastCareful = true;
		StackTraceElement traceElement;
		for (int i = 0, j = traceElements.length; i < j; i++) {
			traceElement = traceElements[i];
			if (traceElement.getClassName().startsWith(packageStart)) {
				if (!lastCareful) lastCareful = true;
				sb.append("\tat ").append(traceElement).append("\n");
			} else {
				if (lastCareful) {
					lastCareful = false;
					sb.append("\t ......").append("\n");
				}
			}
		}
		if (causeString != null) {
			sb.append(causeString);
		}
		return sb.toString();
	}

	/**
	 * 获得异常信息的堆栈
	 *
	 * @param t
	 * @return
	 */
	public static String getExceptionStack(Throwable t) {
		String exceptionStack = null;
		if (t != null) {
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			try {
				t.printStackTrace(pw);
				exceptionStack = sw.toString();
			} finally {
				try {
					sw.close();
				} catch (IOException e) {
				}
				pw.close();
			}
		}
		return exceptionStack;
	}
}
